﻿window.addEventListener("load", function() { rememberExtension.init(); initOverlay(); }, false);

// This adds .indexOf using .prototype.. Usage Array.indexOf("value") returns the ID of the first string with "value" as value
if(![].indexOf) Array.prototype.indexOf = function(needle){ for(var i=0; i<this.length; i++) if(this[i] == needle) return i; return -1 }

//Connect to the database
databaseConnect();
createTables();

// This is for creating the tables, only needs to be run on first load, make routine to check if it contains tables
function createTables() {
  mDBConn.executeSimpleSQL("CREATE TABLE IF NOT EXISTS sites (id INTEGER PRIMARY KEY, url TEXT, first INTEGER, last INTEGER, count INTEGER)");
}

// This is for connecting to the database and creating it if not there
function databaseConnect() {
  var dbfile = Components.classes["@mozilla.org/file/directory_service;1"]
    .getService(Components.interfaces.nsIProperties)
    .get("ProfD", Components.interfaces.nsIFile);

  dbfile.append("remembertosurf.sqlite");

  var storageService = Components.classes["@mozilla.org/storage/service;1"]
    .getService(Components.interfaces.mozIStorageService);

  return mDBConn = storageService.openDatabase(dbfile);
}

// This is the main thingie
var rememberExtension = {
  init: function() {
    var appcontent = document.getElementById("appcontent");   // browser
    if(appcontent)
      appcontent.addEventListener("load", this.onPageLoad, true);
    var messagepane = document.getElementById("messagepane"); // mail
    if(messagepane)
      messagepane.addEventListener("load", this.onPageLoad, true);
  },

  onPageLoad: function(aEvent) {
    getAllSites();

    if (allSites.indexOf(getBrowser().currentURI.spec) != -1) {
      var justnow = Date.now();
      var statement = mDBConn.createStatement("UPDATE sites SET last = ?1, count = (count + 1) WHERE url = ?2");
      statement.bindInt64Parameter(0, justnow);
      statement.bindStringParameter(1, getBrowser().currentURI.spec);
      statement.execute();
    }
  }
}

// This is the function for creating a ranking list and displaying it
function doVooDoo() {
  var justnow = Date.now();
  var statement = mDBConn.createStatement("SELECT * FROM sites");
  var theseSites = new Array();
  
  while(statement.executeStep()) {
    // Do not display items only viewed once and added less then 7 days ago (Give the user a chance to remember recently added items)
    if (statement.getInt64(4) != 1 && statement.getInt64(2) < (Date.now() - 604800)) {
      var average = (statement.getInt64(3) - statement.getInt64(2)) / statement.getInt64(4);
      var sincelast = justnow - statement.getInt64(3);
      var rank = (sincelast / average) * 1000;
      
      rank = Math.round(rank);
      
      // I'm gonna add up to 7 zeroes, anything else is probably crazy, and theres probably a better way to do this through the database or something)
      if (rank < 10) {
        rank = "0000000" + rank;
      } else if (rank < 100) {
        rank = "000000" + rank;
      } else if (rank < 1000) {
        rank = "00000" + rank;
      } else if (rank < 10000) {
        rank = "0000" + rank;
      } else if (rank < 100000) {
        rank = "000" + rank;
      } else if (rank < 1000000) {
        rank = "00" + rank;
      } else if (rank < 10000000) {
        rank = "0" + rank;
      }
      
      var currently = new Array();
      currently[0] = rank;
      currently[1] = statement.getString(1);
      currently[2] = statement.getInt64(4);
      theseSites.push(currently);
    }
  }
  
  theseSites = theseSites.sort();
  theseSites = theseSites.reverse();
  
  var everything = "<table border='1' width='500'><tr><td>Rank</td><td>Visits</td><td>URL</td></tr>";
  
  for (var key in theseSites) {
    everything = everything + "<tr><td><b>" + theseSites[key][0] + "</b></td><td>"+ theseSites[key][2] + "</td><td><a href='" + theseSites[key][1] + "'>" + theseSites[key][1] + "</a></td></tr>";
  }
  
  everything = everything + "</table>";
  
  var savefile = Components.classes["@mozilla.org/file/directory_service;1"]
    .getService(Components.interfaces.nsIProperties)
    .get("ProfD", Components.interfaces.nsIFile);
  savefile.append("remembertosurf.html");
  
  var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
    .createInstance(Components.interfaces.nsIFileOutputStream);
  foStream.init(savefile, 0x02 | 0x08 | 0x20, 0777, 0);
  foStream.write(everything, everything.length);
  foStream.close();

  getBrowser().loadURI(savefile.path);
}

// This is for saving a site to the database through the right click menu!
// Checks if the URL is allready in the database as well, and does not save if it's there!
function rememberSite() {
  getAllSites();
  var current = getBrowser().currentURI.spec;
  if(allSites.indexOf(current) == -1) {
    var justnow = Date.now();
    var statement = mDBConn.createStatement("INSERT INTO sites VALUES (NULL, ?1, ?2, ?3, 1)");
    statement.bindStringParameter(0, current);
    statement.bindInt64Parameter(1, justnow);
    statement.bindInt64Parameter(2, justnow);
    statement.execute();
  }
}

// This removes a site from the database, based on the URL of the currently active site
function removeReminder() {
  var current = getBrowser().currentURI.spec;
  var statement = mDBConn.createStatement("DELETE FROM sites WHERE url = ?1");
  statement.bindStringParameter(0, current);
  statement.execute();
}

function initOverlay() {
 var menu = document.getElementById("contentAreaContextMenu");
 menu.addEventListener("popupshowing", contextPopupShowing, false);
}

function contextPopupShowing() {
  gContextMenu.showItem("rememberSite", !isCurrentInDatabase());
  gContextMenu.showItem("removeReminder", isCurrentInDatabase());
}

// Return true if the current site is in the database
function isCurrentInDatabase() {
  getAllSites();
  var current = getBrowser().currentURI.spec;
  if ( allSites.indexOf(current) != -1 ) {
    return true;
  } else {
    return false;
  }
}

// This is for reading all sites in the database into an Array
function getAllSites() {
  allSites = new Array();
  var statement = mDBConn.createStatement("SELECT * FROM sites");
  while(statement.executeStep()) {
    allSites.push(statement.getString(1));
  }
  return allSites;
}